#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
KairoMoodShare Image Updater Script
根据 KairoMoodShareContentTitle 内容搜索图片并更新 KairoMoodShareContentImages 字段
"""

import json
import os
import sys
import random
import time
import logging
from typing import List, Dict

# 导入图片搜索模块
sys.path.append(os.path.join(os.path.dirname(__file__), 'pinterest/pixabay'))
from simple_image_search import search_images, download_image

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

DEFAULT_IMAGE_DIR = "images"


def kumiBadSafeFilename(name: str) -> str:
    """将名称转换为适合文件名的格式"""
    import re
    safe = re.sub(r'[^A-Za-z0-9_-]', '_', name or "")
    return safe or "item"


def kumiBadDownloadImages(image_urls: List[str], object_id: str, prefix: str, base_dir: str = DEFAULT_IMAGE_DIR) -> List[str]:
    """下载图片并返回文件名列表"""
    safe_object_id = kumiBadSafeFilename(object_id)
    target_dir = os.path.join(base_dir, prefix) if prefix else base_dir
    os.makedirs(target_dir, exist_ok=True)

    downloaded_files: List[str] = []

    for idx, url in enumerate(image_urls, 1):
        # 提取文件扩展名（默认jpg）
        raw_path = url.split('?')[0]
        _, ext = os.path.splitext(raw_path)
        ext = ext.lower()
        if ext not in {'.jpg', '.jpeg', '.png', '.webp', '.gif'}:
            ext = '.jpg'

        file_name = f"{safe_object_id}_{idx}{ext}"
        file_path = os.path.join(target_dir, file_name)

        if download_image(url, file_path):
            downloaded_files.append(file_name)
        else:
            logger.warning("图片下载失败，跳过: %s", url)

    return downloaded_files


def kumiBadUpdateImages(file_path=None, prefix=None, images_per_post=None):
    """为JSON文件中的每个数据根据标题搜索并更新图片

    Args:
        file_path (str, optional): JSON文件路径，如果不提供则提示用户输入
        prefix (str, optional): 字段前缀，如果不提供则提示用户输入
        images_per_post (tuple, optional): 每篇文章的图片数量范围，默认为(3, 7)
    """

    # 如果没有提供文件路径，则提示用户输入
    if file_path is None:
        print("🔍 请输入JSON文件路径:")
        print("   - 可以是绝对路径 (如: /path/to/file.json)")
        print("   - 可以是相对路径 (如: data/file.json)")
        print("   - 直接按回车使用默认文件: pinterest/KairoMoodShareMockData.json")

        user_input = input("📁 文件路径: ").strip()

        # 如果用户直接按回车，使用默认文件
        if not user_input:
            file_path = 'pinterest/KairoMoodShareMockData.json'
            print(f"📋 使用默认文件: {file_path}")
        else:
            file_path = user_input

    # 如果没有提供前缀，则提示用户输入
    if prefix is None:
        print("\n🏷️ 请输入字段前缀:")
        print("   - 例如: KairoMoodShare, WigoTravelChat, MyProject 等")
        print("   - 直接按回车使用默认前缀: KairoMoodShare")

        user_prefix = input("🔤 字段前缀: ").strip()

        # 如果用户直接按回车，使用默认前缀
        if not user_prefix:
            prefix = 'KairoMoodShare'
            print(f"📋 使用默认前缀: {prefix}")
        else:
            prefix = user_prefix

    # 如果没有提供图片数量范围，则设置默认值
    if images_per_post is None:
        images_per_post = (3, 7)

    # 检查文件是否存在
    if not os.path.exists(file_path):
        print(f"❌ 错误: 找不到文件 '{file_path}'")
        return False

    try:
        # 读取JSON文件
        print(f"📖 正在读取文件: {file_path}")
        with open(file_path, 'r', encoding='utf-8') as file:
            kumiBadJsonData = json.load(file)

        print(f"📊 找到 {len(kumiBadJsonData)} 条记录")
        print("🔍 开始为每条记录搜索并更新图片...")
        print("=" * 60)

        # 统计信息
        kumiBadUpdatedCount = 0
        kumiBadTotalImages = 0

        # 为每个数据搜索并更新图片
        for i, kumiBadPost in enumerate(kumiBadJsonData, 1):
            try:
                # 获取标题
                title_field = f"{prefix}ContentTitle"
                content_field = f"{prefix}ContentText"

                kumiBadTitle = kumiBadPost.get(title_field, "")
                
                if not kumiBadTitle:
                    print(f"⚠️  第{i}条记录: 没有找到标题字段 '{title_field}'，使用内容字段 '{content_field}'")
                    kumiBadTitle = kumiBadPost.get(content_field, "")

                if not kumiBadTitle:
                    print(f"⚠️  第{i}条记录: 没有找到标题字段和内容，跳过")  
                    continue

                print(f"🔍 第{i}条记录: 搜索图片 - '{kumiBadTitle}'")

                # 清理标题，提取关键词用于搜索
                search_query = kumiBadCleanTitle(kumiBadTitle)
                print(f"   🔤 搜索关键词: '{search_query}'")

                # 搜索图片 (搜索更多图片以便随机选择)
                search_count = max(15, images_per_post[1] * 2)  # 搜索足够多的图片
                kumiBadFoundImages = search_images(search_query, search_count)

                if not kumiBadFoundImages:
                    print(f"   ❌ 未找到图片")
                    continue

                # 随机选择指定数量的图片
                target_count = random.randint(images_per_post[0], images_per_post[1])
                if len(kumiBadFoundImages) > target_count:
                    kumiBadSelectedImages = random.sample(kumiBadFoundImages, target_count)
                else:
                    kumiBadSelectedImages = kumiBadFoundImages

                # 下载图片并更新字段
                # object_id = kumiBadPost.get("objectId") or f"{prefix}_{i:03d}"
                # downloaded_files = kumiBadDownloadImages(kumiBadSelectedImages, object_id, prefix)

                # if not downloaded_files:
                #     print("   ❌ 图片下载失败，跳过更新")
                #     continue
                # images_field = f"{prefix}ContentImages"
                # kumiBadPost[images_field] = downloaded_files

                # # 不下载直接跟新
                downloaded_files = kumiBadSelectedImages
                images_field = f"{prefix}ContentImages"
                kumiBadPost[images_field] = downloaded_files

                print(f"   ✅ 已更新 {len(downloaded_files)} 张图片")
                kumiBadUpdatedCount += 1
                kumiBadTotalImages += len(downloaded_files)

                # 添加延迟避免过于频繁的请求
                if i < len(kumiBadJsonData):  # 不是最后一条
                    delay = random.uniform(1, 3)  # 1-3秒随机延迟
                    print(f"   ⏳ 等待 {delay:.1f} 秒...")
                    time.sleep(delay)

            except Exception as e:
                print(f"   ❌ 处理第{i}条记录时出错: {str(e)}")
                continue

        # 保存更新后的JSON文件
        print("\n" + "=" * 60)
        print(f"💾 正在保存文件: {file_path}")
        
        # 创建备份文件
        backup_path = file_path.replace('.json', '_backup.json')
        with open(backup_path, 'w', encoding='utf-8') as file:
            json.dump(kumiBadJsonData, file, indent=2, ensure_ascii=False)
        print(f"📋 备份文件已创建: {backup_path}")

        # 保存更新后的文件
        with open(file_path, 'w', encoding='utf-8') as file:
            json.dump(kumiBadJsonData, file, indent=2, ensure_ascii=False)

        print("✅ 图片更新完成！")
        print(f"📊 处理统计:")
        print(f"   - 总记录数: {len(kumiBadJsonData)}")
        print(f"   - 更新成功: {kumiBadUpdatedCount}")
        print(f"   - 总图片数: {kumiBadTotalImages}")
        print(f"   - 平均每条: {kumiBadTotalImages/kumiBadUpdatedCount:.1f} 张图片" if kumiBadUpdatedCount > 0 else "")

        # 验证更新结果
        kumiBadValidatedCount = 0
        for kumiBadPost in kumiBadJsonData:
            images_field = f"{prefix}ContentImages"
            if images_field in kumiBadPost and isinstance(kumiBadPost[images_field], list) and len(kumiBadPost[images_field]) > 0:
                kumiBadValidatedCount += 1

        print(f"🔍 验证结果: {kumiBadValidatedCount}/{len(kumiBadJsonData)} 条记录包含图片")
        return True

    except json.JSONDecodeError:
        print(f"❌ 错误: JSON文件格式不正确 '{file_path}'")
        return False
    except Exception as e:
        print(f"❌ 错误: {str(e)}")
        return False


def kumiBadCleanTitle(title: str) -> str:
    """清理标题，提取适合搜索的关键词

    Args:
        title (str): 原始标题

    Returns:
        str: 清理后的搜索关键词
    """
    # 移除特殊字符和标点符号
    import re
    
    # 保留英文、中文和空格
    cleaned = re.sub(r'[^\w\s\u4e00-\u9fff]', ' ', title)
    
    # 移除多余空格
    cleaned = ' '.join(cleaned.split())
    
    # 如果标题太长，只取前面的关键词
    words = cleaned.split()
    if len(words) > 5:
        cleaned = ' '.join(words[:5])
    
    # 如果没有内容，使用默认搜索词
    if not cleaned.strip():
        cleaned = "mood emotion"
    
    return cleaned.strip()


def kumiBadPreviewUpdates(file_path: str, prefix: str = "KairoMoodShare", limit: int = 5):
    """预览将要更新的内容

    Args:
        file_path (str): JSON文件路径
        prefix (str): 字段前缀
        limit (int): 预览条数限制
    """
    try:
        with open(file_path, 'r', encoding='utf-8') as file:
            data = json.load(file)

        print(f"🔍 预览前 {limit} 条记录的更新计划:")
        print("=" * 60)

        for i, post in enumerate(data[:limit], 1):
            title_field = f"{prefix}ContentTitle"
            title = post.get(title_field, "")
            
            if title:
                search_query = kumiBadCleanTitle(title)
                images_field = f"{prefix}ContentImages"
                current_images = len(post.get(images_field, []))
                
                print(f"第{i}条记录:")
                print(f"  📄 标题: {title}")
                print(f"  🔤 搜索词: {search_query}")
                print(f"  🖼️  当前图片: {current_images} 张")
                print(f"  🎯 将搜索: 3-7 张新图片")
                print()

    except Exception as e:
        print(f"❌ 预览失败: {str(e)}")


def main():
    """主函数，支持命令行参数"""
    import argparse

    parser = argparse.ArgumentParser(description="根据标题搜索并更新图片")
    parser.add_argument('file_path', nargs='?', help='JSON文件路径')
    parser.add_argument('--prefix', default=None, help='字段前缀')
    parser.add_argument('--preview', action='store_true', help='预览模式，不实际更新')
    parser.add_argument('--min-images', type=int, default=3, help='每条记录最少图片数')
    parser.add_argument('--max-images', type=int, default=7, help='每条记录最多图片数')

    args = parser.parse_args()

    if args.preview:
        # 预览模式
        if not args.file_path:
            args.file_path = input("请输入JSON文件路径: ").strip()
            if not args.file_path:
                args.file_path = 'pinterest/KairoMoodShareMockData.json'

        prefix = args.prefix or 'KairoMoodShare'
        kumiBadPreviewUpdates(args.file_path, prefix)
        
        print("👆 以上是预览内容")
        confirm = input("是否继续执行更新? (y/N): ").strip().lower()
        if confirm not in ['y', 'yes']:
            print("❌ 取消更新")
            return

    # 执行更新
    images_range = (args.min_images, args.max_images)
    
    if args.file_path and args.prefix:
        print(f"📋 使用命令行参数:")
        print(f"   文件: {args.file_path}")
        print(f"   前缀: {args.prefix}")
        print(f"   图片数量: {images_range[0]}-{images_range[1]} 张")
        kumiBadUpdateImages(args.file_path, args.prefix, images_range)
    else:
        # 交互模式
        kumiBadUpdateImages(images_per_post=images_range)


if __name__ == "__main__":
    main()
